﻿using System.Collections.Generic;
using System.Linq;

namespace Sidvall.Globalization
{
    public class CultureValueCollection : System.Collections.ObjectModel.KeyedCollection<string, CultureValue>
    {
        #region Public Members

        #region CurrentValue

        public CultureValue CurrentValue
        {
            get
            {
                Sidvall.SystemContext.Current.CultureManager.EnsureCorrectCurrentUICulture();
                return GetOrCreateItem(System.Globalization.CultureInfo.CurrentUICulture.Name);
            }
        }

        #endregion

        #region Add

        public void Add(string name, string value)
        {
            var item = new CultureValue()
            {
                Name = name,
                Value = value,
            };
            Add(item);
        }

        #endregion
        #region AddRange

        public void AddRange(IEnumerable<CultureValue> items)
        {
            if (items == null)
                return;
            foreach (var item in items)
                Add(item);
        }
        public void AddRange(params CultureValue[] items)
        {
            AddRange(items.AsEnumerable());
        }

        #endregion
        #region ContainsCulture

        public bool ContainsCulture(string name)
        {
            var item = GetItem(name);
            return (item != null);
        }

        #endregion
        #region Copy

        public CultureValueCollection Copy()
        {
            var items = new CultureValueCollection();
            foreach (var item in this)
                items.Add(item.Copy());
            return items;
        }

        #endregion
        #region GetItem

        public CultureValue GetItem(string name)
        {
            if (!string.IsNullOrWhiteSpace(name))
            {
                if (Contains(name))
                    return this[name];
                var index = name.LastIndexOf('-');
                while (index > 0)
                {
                    name = name.Substring(0, index);
                    if (Contains(name))
                        return this[name];
                    index = name.LastIndexOf('-');
                }
            }
            return null;
        }

        #endregion
        #region GetKeyForItem

        protected override string GetKeyForItem(CultureValue item)
        {
            if (item == null)
                throw new System.ArgumentNullException(nameof(item));
            return item.Name;
        }

        #endregion
        #region GetOrCreateItem

        public CultureValue GetOrCreateItem(string name)
        {
            var item = GetItem(name);
            if (item != null)
                return item;
            if (!Contains(string.Empty))
            {
                item = new CultureValue()
                {
                    Name = string.Empty,
                    Value = string.Empty,
                };
                Add(item);
            }
            return this[string.Empty];
        }

        #endregion
        #region Deserialize

        public static CultureValueCollection Deserialize(string value)
        {
            return Sidvall.Serialization.SerializerManager.Current.TryDeserialize<CultureValueCollection>(value, () =>
            {
                var items = new CultureValueCollection();
                if (!string.IsNullOrWhiteSpace(value))
                    items.CurrentValue.Value = value;
                return items;
            });
        }

        #endregion
        #region Serialize

        public string Serialize()
        {
            return Serialize(this);
        }
        public static string Serialize(CultureValueCollection items)
        {
            return Serialize(items, null);
        }
        public static string Serialize(CultureValueCollection items, string defaultValue)
        {
            if (items == null)
                return defaultValue;
            return Sidvall.Serialization.SerializerManager.Current.SerializeBusinessObject(items, Sidvall.Serialization.Formatting.None, true);
        }

        #endregion
        #region ToString

        public override string ToString()
        {
            return this.CurrentValue.Value;
        }

        #endregion

        #endregion
        #region Factory Members

        #region CreateInstance

        public static CultureValueCollection CreateInstance(IEnumerable<CultureValue> values)
        {
            return new CultureValueCollection(values);
        }
        public static CultureValueCollection CreateInstance(params CultureValue[] values)
        {
            return new CultureValueCollection(values);
        }
        public static CultureValueCollection CreateInstance(string cultureName1, string cultureValue1)
        {
            var items = new CultureValueCollection();
            items.Add(cultureName1, cultureValue1);
            return items;
        }
        public static CultureValueCollection CreateInstance(string cultureName1, string cultureValue1, string cultureName2, string cultureValue2)
        {
            var items = new CultureValueCollection();
            items.Add(cultureName1, cultureValue1);
            items.Add(cultureName2, cultureValue2);
            return items;
        }
        public static CultureValueCollection CreateInstance(string cultureName1, string cultureValue1, string cultureName2, string cultureValue2, string cultureName3, string cultureValue3)
        {
            var items = new CultureValueCollection();
            items.Add(cultureName1, cultureValue1);
            items.Add(cultureName2, cultureValue2);
            items.Add(cultureName3, cultureValue3);
            return items;
        }
        public static CultureValueCollection CreateInstance(string cultureName1, string cultureValue1, string cultureName2, string cultureValue2, string cultureName3, string cultureValue3,
            string cultureName4, string cultureValue4)
        {
            var items = new CultureValueCollection();
            items.Add(cultureName1, cultureValue1);
            items.Add(cultureName2, cultureValue2);
            items.Add(cultureName3, cultureValue3);
            items.Add(cultureName4, cultureValue4);
            return items;
        }

        #endregion

        #endregion
        #region Constructors

        public CultureValueCollection() : base(System.StringComparer.OrdinalIgnoreCase)
        {
        }
        public CultureValueCollection(IEnumerable<CultureValue> values) : base(System.StringComparer.OrdinalIgnoreCase)
        {
            AddRange(values);
        }
        public CultureValueCollection(params CultureValue[] values) : base(System.StringComparer.OrdinalIgnoreCase)
        {
            AddRange(values);
        }

        #endregion
    }
}
